home *** CD-ROM | disk | FTP | other *** search
/ Software of the Month Club 2000 October / Software of the Month - Ultimate Collection Shareware 277.iso / pc / PROGRAMS / UTILITY / WINLINUX / DATA1.CAB / programs_-_include / LINUX / PAGEMAP.H < prev    next >
C/C++ Source or Header  |  1999-09-17  |  3KB  |  135 lines

  1. #ifndef _LINUX_PAGEMAP_H
  2. #define _LINUX_PAGEMAP_H
  3.  
  4. #include <asm/system.h>
  5.  
  6. /*
  7.  * Page-mapping primitive inline functions
  8.  *
  9.  * Copyright 1995 Linus Torvalds
  10.  */
  11.  
  12. #include <linux/mm.h>
  13. #include <linux/fs.h>
  14.  
  15. static inline unsigned long page_address(struct page * page)
  16. {
  17.     return PAGE_OFFSET + PAGE_SIZE * (page - mem_map);
  18. }
  19.  
  20. #define PAGE_HASH_BITS 12
  21. #define PAGE_HASH_SIZE (1 << PAGE_HASH_BITS)
  22.  
  23. #define PAGE_AGE_VALUE 16
  24.  
  25. extern unsigned long page_cache_size; /* # of pages currently in the hash table */
  26. extern struct page * page_hash_table[PAGE_HASH_SIZE];
  27.  
  28. /*
  29.  * We use a power-of-two hash table to avoid a modulus,
  30.  * and get a reasonable hash by knowing roughly how the
  31.  * inode pointer and offsets are distributed (ie, we
  32.  * roughly know which bits are "significant")
  33.  */
  34. static inline unsigned long _page_hashfn(struct inode * inode, unsigned long offset)
  35. {
  36. #define i (((unsigned long) inode)/(sizeof(struct inode) & ~ (sizeof(struct inode) - 1)))
  37. #define o (offset >> PAGE_SHIFT)
  38. #define s(x) ((x)+((x)>>PAGE_HASH_BITS))
  39.     return s(i+o) & (PAGE_HASH_SIZE-1);
  40. #undef i
  41. #undef o
  42. #undef s
  43. }
  44.  
  45. #define page_hash(inode,offset) (page_hash_table+_page_hashfn(inode,offset))
  46.  
  47. static inline struct page * __find_page(struct inode * inode, unsigned long offset, struct page *page)
  48. {
  49.     goto inside;
  50.     for (;;) {
  51.         page = page->next_hash;
  52. inside:
  53.         if (!page)
  54.             goto not_found;
  55.         if (page->inode != inode)
  56.             continue;
  57.         if (page->offset == offset)
  58.             break;
  59.     }
  60.     /* Found the page. */
  61.     atomic_inc(&page->count);
  62.     set_bit(PG_referenced, &page->flags);
  63. not_found:
  64.     return page;
  65. }
  66.  
  67. static inline struct page *find_page(struct inode * inode, unsigned long offset)
  68. {
  69.     return __find_page(inode, offset, *page_hash(inode, offset));
  70. }
  71.  
  72. static inline void remove_page_from_hash_queue(struct page * page)
  73. {
  74.     if(page->pprev_hash) {
  75.         if(page->next_hash)
  76.             page->next_hash->pprev_hash = page->pprev_hash;
  77.         *page->pprev_hash = page->next_hash;
  78.         page->pprev_hash = NULL;
  79.     }
  80.     page_cache_size--;
  81. }
  82.  
  83. static inline void __add_page_to_hash_queue(struct page * page, struct page **p)
  84. {
  85.     page_cache_size++;
  86.     if((page->next_hash = *p) != NULL)
  87.         (*p)->pprev_hash = &page->next_hash;
  88.     *p = page;
  89.     page->pprev_hash = p;
  90. }
  91.  
  92. static inline void add_page_to_hash_queue(struct page * page, struct inode * inode, unsigned long offset)
  93. {
  94.     __add_page_to_hash_queue(page, page_hash(inode,offset));
  95. }
  96.  
  97. static inline void remove_page_from_inode_queue(struct page * page)
  98. {
  99.     struct inode * inode = page->inode;
  100.  
  101.     page->inode = NULL;
  102.     inode->i_nrpages--;
  103.     if (inode->i_pages == page)
  104.         inode->i_pages = page->next;
  105.     if (page->next)
  106.         page->next->prev = page->prev;
  107.     if (page->prev)
  108.         page->prev->next = page->next;
  109.     page->next = NULL;
  110.     page->prev = NULL;
  111. }
  112.  
  113. static inline void add_page_to_inode_queue(struct inode * inode, struct page * page)
  114. {
  115.     struct page **p = &inode->i_pages;
  116.  
  117.     inode->i_nrpages++;
  118.     page->inode = inode;
  119.     page->prev = NULL;
  120.     if ((page->next = *p) != NULL)
  121.         page->next->prev = page;
  122.     *p = page;
  123. }
  124.  
  125. extern void __wait_on_page(struct page *);
  126. static inline void wait_on_page(struct page * page)
  127. {
  128.     if (PageLocked(page))
  129.         __wait_on_page(page);
  130. }
  131.  
  132. extern void update_vm_cache(struct inode *, unsigned long, const char *, int);
  133.  
  134. #endif
  135.